<?php

require_once 'VersionControl/SVN.php';

class SVNBot_SVN_Updater 
{
	private $_repo;
	private $_loggers = array();
	private $_wrk;
	private $_svnstack;


	public function __construct($repo, $wrk, $svnpath) 
	{
		$this->_repo = $repo;	
		$this->_wrk = $wrk;
		$this->_svn = VersionControl_SVN::factory(array('info', 'update', 'log'));
		$this->_svn->info->svn_path = $svnpath;
		$this->_svn->info->use_escapeshellcmd = false;
		$this->_svn->update->svn_path = $svnpath;
		$this->_svn->update->use_escapeshellcmd = false;
		$this->_svn->log->svn_path = $svnpath;
		$this->_svn->log->use_escapeshellcmd = false;
		$this->_svnstack = PEAR_ErrorStack::singleton('VersionControl_SVN');
	}

	public function addLogger($logger) 
	{
		$this->_loggers[] = $logger;
	}

	private function _getError() 
	{
		$ret = '';
		foreach ($this->_svnstack->getErrors() as $err) {
			$ret .= "\n" . $err['message'] . "\n";
		}
		return $ret;
	}

	public function update() 
	{
		$wrkversion = $this->getVersion($this->_wrk);
		$repoversion = $this->getVersion($this->_repo);

		if (!$wrkversion || !$repoversion) {
			return false;
		}

		if ($repoversion > $wrkversion) {
			$cwd = getcwd();
			chdir($this->_wrk);
			if ($this->_svn->update->run()) {
				$this->_log($this->fetchLog($this->_repo, $wrkversion + 1, $repoversion));
			} else {
				$this->_log($this->_getError());
			}
			chdir($cwd);
		}
	}

	public function fetchLog($url, $from, $to) 
	{
		$options = array('r' => $from . ':' . $to, 'v' => true);
		$log = $this->_svn->log->run(array($url), $options);
		if ($log) {
			return $this->formatLog($log);
		} else {
			$this->_log($this->_getError());
		}
	}

	public function getVersion($url) 
	{
		$out = $this->_svn->info->run(array($url));
		if ($out) {
			preg_match('/Revision: (\d+)/', $out, $matches);
			return $matches[1];
		} else {
			$this->_log($this->_getError());
			return false;
		}
	}

	private function _log($message) 
	{
		foreach ($this->_loggers as $logger) {
			$logger->log($message);
		}
	}

	public function formatLog($log) 
	{
		$ret = '' . "\n";
		foreach ($log as $entry) {
			$ret .= '=================================================' . "\n";
			$ret .= 'Revision ' . $entry['REVISION'] . ' by ' . $entry['AUTHOR'] . ':' . "\n";
			$ret .= $entry['MSG'] . "\n";
			$ret .= '---' . "\n";

			if (isset($entry['PATHS']) && is_array($entry['PATHS'])) {
				foreach ($entry['PATHS'] as $path) {
					$ret .= $path['ACTION'] . ' ' . $path['PATH'] . "\n";
				}
			}
			$ret .= '=================================================';
			$ret .= "\n\n";
		}
		return $ret;
	}
}
